home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3 (Developer)…68k, x86, SPARC, PA-RISC] / NeXTSTEP 3.3 Dev Intel.iso / usr / sybase / sample / dblibrary / twophase.c < prev   
C/C++ Source or Header  |  1993-04-22  |  6KB  |  235 lines

  1. /*    
  2. **    twophase.c
  3. **
  4. **    Demo of Two-Phase Commit Service
  5. **
  6. **    This example uses the two-phase commit service
  7. **    to perform a simultaneous update on two servers.
  8. **    In this example, one of the servers participating 
  9. **    in the distributed transaction also functions as 
  10. **    the commit service.
  11. **
  12. **    In this particular example, the same update is 
  13. **    performed on both servers. You can, however, use 
  14. **    the commit server to perform completely different 
  15. **    updates on each server.
  16. **
  17. */
  18.  
  19. #include <stdio.h>
  20. #include <sybfront.h>
  21. #include <sybdb.h>
  22.  
  23. int err_handler();
  24. int msg_handler();
  25.  
  26. char     cmdbuf[256];
  27. char     xact_string[128];
  28.  
  29. main()
  30. {
  31.  
  32.     DBPROCESS     *dbproc_server1; 
  33.     DBPROCESS     *dbproc_server2;
  34.     DBPROCESS     *dbproc_commit;
  35.     LOGINREC      *login;
  36.     int           commid;
  37.  
  38.     RETCODE       ret_server1;
  39.     RETCODE       ret_server2;
  40.  
  41.     /* Initialize DB-Library. */
  42.     if (dbinit() == FAIL)
  43.         exit(ERREXIT);
  44.  
  45.     dberrhandle(err_handler);
  46.     dbmsghandle(msg_handler);
  47.  
  48.     printf("Demo of Two Phase Commit\n");
  49.  
  50.     /* Open connections with the servers and the commit service. */
  51.     login = dblogin();
  52.     DBSETLPWD(login, "server_password");
  53.     DBSETLAPP(login, "twophase");
  54.  
  55.     dbproc_server1 = dbopen (login, "SERVICE");
  56.     dbproc_server2 = dbopen (login, "PRACTICE");
  57.     dbproc_commit = open_commit (login, "SERVICE");
  58.  
  59.     if (dbproc_server1 == NULL || 
  60.         dbproc_server2 == NULL || 
  61.         dbproc_commit  == NULL)
  62.     {
  63.         printf (" Connections failed!\n");
  64.         exit (ERREXIT);
  65.     }
  66.  
  67.     /* Use the "pubs" database. */
  68.     sprintf(cmdbuf, "use pubs");
  69.     dbcmd(dbproc_server1, cmdbuf);
  70.     dbsqlexec(dbproc_server1);
  71.     dbcmd(dbproc_server2, cmdbuf);
  72.     dbsqlexec(dbproc_server2);
  73.  
  74.     /* Start the distributed transaction on the commit service. */
  75.     commid = start_xact(dbproc_commit, "demo", "test", 2);
  76.  
  77.     /* Build the transaction name. */
  78.     build_xact_string ("test", "SERVICE", commid, xact_string);
  79.  
  80.     /* Build the first command buffer. */
  81.     sprintf(cmdbuf, "BEGIN TRANSACTION %s", xact_string);
  82.  
  83.     /* Begin the transactions on the different servers. */
  84.     dbcmd(dbproc_server1, cmdbuf);
  85.     dbsqlexec(dbproc_server1);
  86.     dbcmd(dbproc_server2, cmdbuf);
  87.     dbsqlexec(dbproc_server2);
  88.  
  89.     /* Do various updates. */
  90.     sprintf(cmdbuf, " update titles set price = $1.50 where");
  91.     strcat(cmdbuf, " title_id = 'BU1032'");
  92.     dbcmd(dbproc_server1, cmdbuf);
  93.     ret_server1 = dbsqlexec(dbproc_server1);
  94.     dbcmd(dbproc_server2, cmdbuf);
  95.     ret_server2 =dbsqlexec(dbproc_server2);
  96.     if (ret_server1 == FAIL || ret_server2 == FAIL)
  97.     {
  98.         /* Some part of the transaction failed. */
  99.         printf(" Transaction aborted -- dbsqlexec failed\n");
  100.         abortall(dbproc_server1, dbproc_server2, dbproc_commit, commid);
  101.     }
  102.  
  103.     /* Find out if all servers can commit the transaction. */
  104.     sprintf(cmdbuf, "PREPARE TRANSACTION");
  105.     dbcmd(dbproc_server1, cmdbuf);
  106.     dbcmd(dbproc_server2, cmdbuf);
  107.     ret_server1 = dbsqlexec(dbproc_server1);
  108.     ret_server2 = dbsqlexec(dbproc_server2);
  109.     if (ret_server1 == FAIL || ret_server2 == FAIL)
  110.     {
  111.         /* One or both of the servers failed to prepare. */
  112.         printf(" Transaction aborted -- PREPARE failed\n");
  113.         abortall(dbproc_server1, dbproc_server2, dbproc_commit, commid);
  114.     }
  115.  
  116.     /* Commit the transaction. */
  117.     if (commit_xact(dbproc_commit, commid) == FAIL)
  118.     {
  119.         /* The commit server failed to record the commit. */
  120.         printf( " Transaction aborted -- commit_xact failed\n");
  121.         abortall(dbproc_server1, dbproc_server2, dbproc_commit, commid);
  122.         exit(ERREXIT);
  123.     }
  124.  
  125.     /* The transaction has successfully committed.  Inform the servers. */
  126.     sprintf(cmdbuf, "COMMIT TRANSACTION");
  127.     dbcmd(dbproc_server1, cmdbuf);
  128.     if (dbsqlexec(dbproc_server1) != FAIL)
  129.         remove_xact(dbproc_commit, commid, 1);
  130.     dbcmd(dbproc_server2, cmdbuf);
  131.     if (dbsqlexec(dbproc_server2) != FAIL)
  132.         remove_xact(dbproc_commit, commid, 1);
  133.  
  134.     /* Close the connection to the commit server. */
  135.     close_commit(dbproc_commit);
  136.  
  137.     printf( "We made it!\n");
  138.     dbexit();
  139.     exit(STDEXIT);
  140. }
  141.  
  142. /* Function to abort the distributed transaction. */
  143.  
  144. abortall( dbproc_server1, dbproc_server2, dbproc_commit, commid )
  145. DBPROCESS      *dbproc_server1; 
  146. DBPROCESS      *dbproc_server2;
  147. DBPROCESS      *dbproc_commit;
  148. int            commid;
  149. {
  150.     /* Some part of the transaction failed. */
  151.  
  152.     /* Inform the commit server of the failure. */
  153.     abort_xact(dbproc_commit, commid);
  154.  
  155.     /* Roll back the transactions on the different servers. */
  156.     sprintf(cmdbuf, "ROLLBACK TRANSACTION");
  157.     dbcmd(dbproc_server1, cmdbuf);
  158.     if (dbsqlexec(dbproc_server1) != FAIL)
  159.         remove_xact(dbproc_commit, commid, 1);
  160.     dbcmd(dbproc_server2, cmdbuf);
  161.     if (dbsqlexec(dbproc_server2) != FAIL)
  162.         remove_xact(dbproc_commit, commid, 1);
  163.  
  164.     dbexit();
  165.     exit(ERREXIT);
  166. }
  167.  
  168. /* Message and error handling functions. */
  169.  
  170. int msg_handler(dbproc, msgno, msgstate, severity, msgtext, 
  171.                 servername, procname, line)
  172.  
  173. DBPROCESS       *dbproc;
  174. DBINT           msgno;
  175. int             msgstate;
  176. int             severity;
  177. char            *msgtext;
  178. char            *servername;
  179. char            *procname;
  180. DBUSMALLINT     line;
  181.  
  182. {
  183.     /*   Msg 5701 is just a USE DATABASE message, so skip it.  */
  184.     if (msgno == 5701)
  185.         return (0);
  186.  
  187.     /*  Print any severity 0 message as is, without extra stuff.  */
  188.     if (severity == 0)
  189.     {
  190.         printf ("%s\n",msgtext);
  191.         return (0);
  192.     }
  193.  
  194.     printf ("Msg %ld, Level %d, State %d\n", 
  195.             msgno, severity, msgstate);
  196.  
  197.     if (strlen(servername) > 0)
  198.         printf ("Server '%s', ", servername);
  199.     if (strlen(procname) > 0)
  200.         printf ("Procedure '%s', ", procname);
  201.     if (line > 0)
  202.         printf ("Line %d", line);
  203.  
  204.     printf("\n\t%s\n", msgtext);
  205.  
  206.     if (severity >= 16)
  207.     {
  208.         printf("Program Terminated! Fatal SQL Server error.\n");
  209.         exit(ERREXIT);
  210.     }
  211.  
  212.     return (0);   
  213. }
  214.  
  215. int err_handler(dbproc, severity, dberr, oserr, dberrstr, oserrstr)
  216. DBPROCESS    *dbproc;
  217. int          severity;
  218. int          dberr;
  219. int          oserr;
  220. char         *dberrstr;
  221. char         *oserrstr;
  222. {
  223.     if ((dbproc == NULL) || (DBDEAD(dbproc)))
  224.         return (INT_EXIT);
  225.     else
  226.     {
  227.         printf ("DB-Library error: \n\t%s\n", dberrstr);
  228.  
  229.         if (oserr != DBNOERR)
  230.             printf ("Operating system error:\n\t%s\n", oserrstr);
  231.     }
  232.  
  233.     return (INT_CANCEL);
  234. }
  235.